import CellGSModel from "./CellGSModel";
import {
    EventKey
} from "../common_for_guosheng/Key";

import {
    GameGSState
} from "./GameGSState";
import {
    GameGSData
} from "./GameGSData";
import {
    GAMEMODEGS,
    GetSurpriseLevelgs,
    GetOnecolorgsLevel,
    GetGameGridCount
} from "./GameGSDefine";

export default class GridGSModel {
    constructor(params) {
        GameGSData.saveLastGame(null);
        GameGSData.setGameMode(GAMEMODEGS.DEFAULT)
        if (params) {
            GameGSState.setLevel(params.level);
            GameGSState.setScore(params.score);
        } else {
            params = {};
        }
        this.init(params.boardData);
    }

    init(boardData) {
        if (boardData) {
            this.produceGridWithData(boardData);
        } else {
            let level = GameGSState.getLevel();
            let levels = GetOnecolorgsLevel();
            let superLevels = GetSurpriseLevelgs();
            if (level % GetGameGridCount() === 0) {
                let boardData;
                if (level === 0) {
                    let randomIndex = F.Utils.random(0, levels.length - 1)
                    boardData = levels[randomIndex]
                } else {
                    let randomIndex = F.Utils.random(0, superLevels.length - 1)
                    boardData = superLevels[randomIndex];
                }
                this.produceGridWithData(boardData);
            } else {
                this.produceGrid();
            }
        }
    }

    clearCellGSModels() {
        this.cellModels = null;
    }

    produceGrid() {
        this.cellModels = [];
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            this.cellModels[y] = [];
            for (let x = 0; x < count; x++) {
                let randomColor = F.Utils.random(1, 5);
                let cellModel = this.spawnCellGSModel(randomColor, x, y);
                this.cellModels[y][x] = cellModel;
            }
        }
    }

    produceGridWithData(boardData) {
        this.cellModels = [];
        let count = GetGameGridCount();

        for (let y = 0; y < count; y++) {
            this.cellModels[y] = [];
            for (let x = 0; x < count; x++) {
                if (boardData[y][x] == -1) {
                    continue;
                }
                let cellModel = this.spawnCellGSModel(boardData[y][x], x, y);
                this.cellModels[y][x] = cellModel;
            }
        }
    }

    spawnCellGSModel(color, x, y) {
        let cellModel = new CellGSModel();
        cellModel.setColor(color);
        cellModel.setXY(x, y);
        return cellModel;
    }

    getCellGSModels() {
        return this.cellModels
    }
    getCellGSModel(x, y) {
        if (!this.cellModels[y]) {
            return false;
        }
        return this.cellModels[y][x];
    }
    clickCell(x, y) {
        let cellModel = this.getCellGSModel(x, y);
        if (!cellModel) {
            return [];
        }
        let list = this.getSameColorCellGSModelList(cellModel);
        return list;
    }

    // 获取同色cellModel数组
    getSameColorCellGSModelList(cellModel) {
        if (!cellModel) {
            return [];
        }
        let startPos = cellModel.getXY();
        let openList = [cellModel];
        let closeList = [];
        let sameColorList = [];
        let color = cellModel.color;
        let tFunc = () => {
            let cellModel = openList.pop();

            // 获取上下左右四个格子
            let topCellGSModel = this.getCellGSModel(cellModel.x, cellModel.y + 1);
            let bottomCellGSModel = this.getCellGSModel(cellModel.x, cellModel.y - 1);
            let rightCellGSModel = this.getCellGSModel(cellModel.x + 1, cellModel.y);
            let leftCellGSModel = this.getCellGSModel(cellModel.x - 1, cellModel.y);

            cellModel.space = Math.abs(startPos.x - cellModel.x) + Math.abs(startPos.y - cellModel.y)

            closeList.push(cellModel);
            if (cellModel.color === color) {
                sameColorList.push(cellModel);
            }

            if (topCellGSModel && topCellGSModel.color === color) {
                if (!F.Common.isInArr(topCellGSModel, closeList) &&
                    !F.Common.isInArr(topCellGSModel, sameColorList) &&
                    !F.Common.isInArr(topCellGSModel, openList)) {
                    openList.push(topCellGSModel);
                }
            }
            if (bottomCellGSModel && bottomCellGSModel.color === color) {
                if (!F.Common.isInArr(bottomCellGSModel, closeList) &&
                    !F.Common.isInArr(bottomCellGSModel, sameColorList) &&
                    !F.Common.isInArr(bottomCellGSModel, openList)) {
                    openList.push(bottomCellGSModel);
                }
            }
            if (rightCellGSModel && rightCellGSModel.color === color) {
                if (!F.Common.isInArr(rightCellGSModel, closeList) &&
                    !F.Common.isInArr(rightCellGSModel, sameColorList) &&
                    !F.Common.isInArr(rightCellGSModel, openList)) {
                    openList.push(rightCellGSModel);
                }
            }
            if (leftCellGSModel && leftCellGSModel.color === color) {
                if (!F.Common.isInArr(leftCellGSModel, closeList) &&
                    !F.Common.isInArr(leftCellGSModel, sameColorList) &&
                    !F.Common.isInArr(leftCellGSModel, openList)) {
                    openList.push(leftCellGSModel);
                }
            }

            if (openList.length > 0) {
                tFunc();
            }
        }
        tFunc();

        return sameColorList;
    }

    // 从cellModels中移除数组中的cellmodel
    removeCellGSModelByList(list) {
        if (!list) {
            return;
        }
        for (let i = 0; i < list.length; i++) {
            this.cellModels[list[i].y][list[i].x] = null;
        }
    }

    // 下落
    cellFall() {
        for (let y = 0; y < this.cellModels.length; y++) {
            for (let x = 0; x < this.cellModels[y].length; x++) {
                if (this.cellModels[y][x]) {
                    continue;
                }
                for (let yy = y + 1; yy < this.cellModels.length; yy++) {
                    if (!this.cellModels[yy][x]) {
                        continue;
                    }
                    this.cellModels[y][x] = this.cellModels[yy][x];
                    this.cellModels[yy][x] = null;
                    this.cellModels[y][x].y = y;
                    this.cellModels[y][x].fallCount = yy - y;
                    break;
                }
            }
        }
    }
    // 聚拢
    cellGather() {
        for (let x = 0; x < this.cellModels.length; x++) {
            let gatherCount = 0;
            for (let xx = x; xx < this.cellModels.length; xx++) {
                let isEmpty = true;
                for (let y = 0; y < this.cellModels.length; y++) {
                    if (this.cellModels[y][xx]) {
                        isEmpty = false;
                    }
                }

                if (isEmpty) {
                    gatherCount++;
                } else {
                    break;
                }
            }
            if (gatherCount == 0) {
                continue;
            }
            for (let y = 0; y < this.cellModels.length; y++) {
                let cellModel = this.cellModels[y][x + gatherCount];
                this.cellModels[y][x + gatherCount] = null;
                this.cellModels[y][x] = cellModel;
                if (cellModel) {
                    cellModel.gatherCount = gatherCount;
                    cellModel.x = x;
                }
            }
        }
    }
    // 检查是否结束
    checkIsOver() {
        for (let y = 0; y < this.cellModels.length; y++) {
            for (let x = 0; x < this.cellModels[y].length; x++) {
                let cellModel = this.cellModels[y][x];
                if (!cellModel) {
                    continue;
                }
                let list = this.getSameColorCellGSModelList(cellModel);
                if (list.length > 1) {
                    return false;
                }

            }
        }

        return true;
    }

    // 打乱棋盘
    shuffleBoard() {
        var arr = [].concat.apply([], this.cellModels);
        let arr2 = F.Utils.shuffle(arr);
        var arr3 = [];
        for (var i = 0; i < arr.length; i++) {
            arr3[i] = [];
            for (var j = 0; j < arr[i].length; j++) {
                let cellModel = arr2.shift();
                cellModel.setXY(j, i);
                arr3[i][j] = cellModel;
            }
        }
        let oldArr = this.cellModels;
        this.cellModels = arr3;
        return oldArr;
    }

    checkPass() {
        if (this.hadPass) {
            return;
        }
        if (GameGSState.getScore() >= this.getLevelScore()) {
            this.hadPass = true;
            F.OnEvent.fire(EventKey.EVENT_PASS_LEVEL);
        }
    }

    getIsPass() {
        return this.hadPass;
    }

    // 保存进度
    saveLastGame() {
        // 生成当前挑战数据
        let challengeData = {}
        challengeData.level = GameGSState.getLevel();
        challengeData.score = GameGSState.getScore();

        if (this.cellModels && this.cellModels.length > 0) {
            let boardData = [];
            let count = GetGameGridCount();
            for (let y = 0; y < count; y++) {
                boardData[y] = [];
                for (let x = 0; x < count; x++) {
                    let cellModel = this.cellModels[y][x];
                    let color = -1;
                    if (cellModel) {
                        color = cellModel.getColor();
                    }
                    boardData[y][x] = color;
                }
            }
            challengeData.boardData = boardData;
        }

        GameGSData.saveLastGame(challengeData);
    }

    // 获取最后的分数
    getBonusScore(count) {
        let arr = [2000, 1980, 1920, 1820, 1680, 1500, 1280, 1020, 720, 380, 0];
        let score;
        if (count <= arr.length - 1) {
            score = arr[count];
        } else {
            score = 0
        }
        return score;
    }

    getLevelScore() {
        if (cc.sys.browserType === cc.sys.BROWSER_TYPE_WECHAT_GAME) {
            return GameGSState.getLevel() * 2000 + this.extrendAddScore();
        } else {
            return GameGSState.getLevel() * 100;
        }
    }

    extrendAddScore() {
        let level = GameGSState.getLevel();
        if (level >= 1 && level < 10) {
            return 1000;
        } else if (level >= 10 && level < 20) {
            return 1500;
        } else if (level >= 20 && level < 30) {
            return 2000;
        } else if (level >= 30 && level < 40) {
            return 2500;
        } else if (level >= 40 && level < 50) {
            return 3000;
        } else {
            return 3500;
        }
    }

    destroyOneCell(x, y) {
        if (!this.cellModels[y][x]) {
            return false;
        }
        let cellModel = this.cellModels[y][x];
        this.cellModels[y][x] = null;
        return cellModel;
    }

    changeColor(x, y, color) {
        if (!this.cellModels[y][x]) {
            return false;
        }
        let cellModel = this.cellModels[y][x];
        cellModel.setColor(color);
        return cellModel;
    }
}